using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

namespace Super
{
	[CreateAssetMenu(fileName = "ExcelNote", menuName = "Super/Create ExcelNote")]
	public class ExcelNoteSO : ScriptableObject
	{

		public List<ExcelNoteNode> notes = new List<ExcelNoteNode>();
		public string enumExcelPath;
		public string lastExcelPath;

		[SerializeField]
		private static ExcelNoteSO ins;
		public static ExcelNoteSO Ins
		{
			get
			{
				if (ins == null)
				{
					ins = Resources.Load<ExcelNoteSO>("ExcelNote");
				}
				return ins;
			}
		}

		private void AddNode(ExcelNoteNode node)
		{
			ExcelNoteNode oldNode = null;
			int oldNodeIndex = -1;
			for (int i = 0; i < notes.Count; i++)
			{
				if (node.excelPath == notes[i].excelPath)
				{
					oldNode = notes[i];
					oldNodeIndex = i;
					break;
				}
			}
			if (oldNode != null)
			{
				ClearNodeCache(oldNode);
				notes.RemoveAt(oldNodeIndex);
			}

			notes.Add(node);
#if UNITY_EDITOR
			EditorUtility.SetDirty(this);
#endif
		}

		public ExcelNoteNode SetTableInfo(string excelPath)
		{
			string relativePath = GlobalUtil.GetAssetsRelativePath(excelPath);
			ExcelNoteNode node = new ExcelNoteNode(relativePath);
			List<string> sheetNames = ExcelUtil.GetExcelTableNames(relativePath);
			for (int i = 0; i < sheetNames.Count; i++)
			{
				ExcelTableInfo info = ExcelUtil.GetTableInfo(relativePath, i);
				string SOPath = string.Format(PathSettingSO.Ins.excelTableSOPath, info.tableName);
				node.nodeNames.Add(info.nodeName);
				node.tableNames.Add(info.tableName);
				node.scriptPaths.Add(info.scriptPath);
				node.SOPaths.Add(SOPath);
			}
			AddNode(node);
			return node;
		}

		public ExcelNoteNode FindTableInfo(string excelPath)
		{
			for (int i = 0; i < notes.Count; i++)
			{
				if (notes[i].excelPath == excelPath)
				{
					return notes[i];
				}
			}
			return null;
		}

		public Type GetTableNodeType(ExcelNoteNode node, int index)
		{
			Type type = null;
			if (node != null)
			{
				type = Type.GetType("Super." + node.nodeNames[index]);
			}
			return type;
		}
		public Type GetTableClassType(ExcelNoteNode node, int index)
		{
			Type type = null;
			if (node != null)
			{
				type = Type.GetType("Super." + node.tableNames[index]);
			}
			return type;
		}

		public void Remove(string excelPath)
		{
			for (int i = 0; i < notes.Count; i++)
			{
				if (notes[i].excelPath == excelPath)
				{
					ClearNodeCache(notes[i]);
					notes.RemoveAt(i);
					break;
				}
			}
#if UNITY_EDITOR
			EditorUtility.SetDirty(this);
#endif
		}
		public void ClearNodeCache(ExcelNoteNode node)
		{
#if UNITY_EDITOR
			foreach (string path in node.SOPaths)
				AssetDatabase.DeleteAsset(path);

			foreach (string path in node.scriptPaths)
				AssetDatabase.DeleteAsset(path);
#endif
		}

		public bool CheckIfSetTableInfo(string excelPath)
		{
			string relativePath = GlobalUtil.GetAssetsRelativePath(excelPath);
			ExcelNoteNode node = FindTableInfo(relativePath);
			if (node == null || node.nodeNames.Count == 0 || node.tableNames.Count == 0)
			{
				return false;
			}
			return true;
		}

		public bool CheckIfSetTableSO(string excelPath)
		{
			string relativePath = GlobalUtil.GetAssetsRelativePath(excelPath);
			ExcelNoteNode node = FindTableInfo(relativePath);
			if (node == null || node.SOPaths.Count == 0)
			{
				return false;
			}

			for (int i = 0; i < node.SOPaths.Count; i++)
			{
				if (!AssetUtil.AddrExist(node.SOPaths[i]))
				{
					return false;
				}
			}
			return true;
		}
	
		public void SaveEnumPath(string path)
		{
			enumExcelPath = path;
			#if UNITY_EDITOR
			EditorUtility.SetDirty(this);
			#endif	
		}

		public void SaveLastPath(string path)
		{
			lastExcelPath = path;
			#if UNITY_EDITOR
			EditorUtility.SetDirty(this);
			#endif
		}
	}
}
